﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Pvr_UnitySDKAPI;

namespace Assets.Scripts.TDu3DWork
{
    class TDuVRDevicesWorker
    {
        //碰撞的射线;
        private Ray m_ray;
        private RaycastHit m_rayCastHit;

        private bool m_noClick;
        public float m_rayDefaultLength = 4;

        //碰撞后的物体
        private Transform m_currentHit;
        private Transform m_lastHit;

        //相关材质;
        [SerializeField]
        private Material m_normat;
        [SerializeField]
        private Material m_gazemat;
        [SerializeField]
        private Material m_clickmat;

        private Transform m_dragObj;
        float m_disX, m_disY, m_disZ;
        GameObject m_referenceObj;


        //传送相关变量;
        public float fadeTime = 0.2f;

        public bool IsScreenFade = false;
        private Vector3 currentHitPoint = Vector3.zero;
        private Color fadeColor = new Color(0.9f, 0.9f, 0.9f, 0f);
        private Material fademat;


        public TDuVRDevicesWorker()
        {
            m_ray = new Ray();
            m_rayCastHit = new RaycastHit();
            m_referenceObj = new GameObject("ReferenceObj");
        }

        public void onControllerAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            switch (e.m_emVRControllerCmd)
            {
                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_X:
                    onXButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_Y:
                    onYButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_LEFT:
                    onLeftButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_HOME:
                    onLeftHomeAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_TRIGGER:
                    onTriggerAction2(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_APP:
                    onLeftAppButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_TOUCHPAD:
                    onLeftTouchapadAction(sender, e);
                    break;

                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_A:
                    onAButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_B:
                    onBButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_RIGHT:
                    onRightButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_HOME:
                    onRightHomeAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_TRIGGER:
                    onTriggerAction2(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_APP:
                    onRightAppButtonAction(sender, e);
                    break;
                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_TOUCHPAD:
                    onRightTouchapadAction(sender, e);
                    break;

                case TDuVRControllerEventArgs.VRCONTROLLCMD.LEFT_CONTROLLER_TOUCHPAD_UP:
                case TDuVRControllerEventArgs.VRCONTROLLCMD.RIGHT_CONTROLLER_TOUCHPAD_UP:
                    onTeleport(sender, e);
                    break;

                case TDuVRControllerEventArgs.VRCONTROLLCMD.NONE:
                default:
                    break;
            }
        }

        //不精确的碰撞;
        public void onTriggerAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("---------Trigger button pushed--------");
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;
            m_ray.direction = baseWorker.m_currentController.transform.forward - baseWorker.m_currentController.transform.up * 0.25f;
            m_ray.origin = baseWorker.m_currentController.transform.Find("start").position;

            RaycastHit hit;
            if (Physics.Raycast(m_ray, out hit))
            {
                Debug.Log("---------VR hit object name:" + hit.collider.name);
                baseWorker.hitVarialbeNode(hit.collider.name);
            }
            else
            {
                Debug.Log("---------VR not hit boject ");
            }
        }

        //来源于ControllerDemo的碰撞，考虑了材质的误差
        public void onTriggerAction2(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("---------Trigger2 button pushed--------");
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;

            hitCheck(sender);
            if (m_lastHit != null)
            {
                Debug.Log("---------VR hit object name:" + m_lastHit.transform.name);
                baseWorker.hitVarialbeNode(m_lastHit.transform.name);
            }
        }

        public void onXButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("--------X Button pushed----------");
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;

            baseWorker.m_mainCanvas.SetActive(!baseWorker.m_mainCanvas.activeSelf);
            Application.Quit();
        }

        public void onYButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("--------Y Button pushed----------");
        }

        public void onLeftButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("--------Left Button pushed----------");
        }

        public void onRightButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("--------Right Button pushed----------");
        }

        public void onAButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("--------A Button pushed----------");
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;

            baseWorker.m_mainCanvas.SetActive(!baseWorker.m_mainCanvas.activeSelf);
        }

        public void onBButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("--------B Button pushed----------");
        }

        public void onLeftHomeAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {

        }

        public void onLeftAppButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {

        }

        public void onLeftTouchapadAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("---------Left Touchpad pushed--------");
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;

            hitCheck(sender);

            if (m_lastHit != null)
            {
                Debug.Log("-------hitpoint");
                baseWorker.m_teleportLine.enabled = true;
                currentHitPoint = m_rayCastHit.point;
                if (HitFloor(ref m_rayCastHit) && m_rayCastHit.point != null)
                {
                    baseWorker.m_teleportPoint.transform.position = m_rayCastHit.point;
                    baseWorker.m_teleportPoint.SetActive(true);
                }
            }
            else
            {
                baseWorker.m_teleportPoint.SetActive(false);
            }

            baseWorker.drawLine();
        }

        public void onRightHomeAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {

        }

        public void onRightAppButtonAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {

        }

        public void onRightTouchapadAction(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            Debug.Log("---------Right Touchpad pushed--------");
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;

            hitCheck(sender);

            if (m_lastHit != null)
            {
                baseWorker.m_teleportLine.enabled = true;
                currentHitPoint = m_rayCastHit.point;
                if (HitFloor(ref m_rayCastHit) && m_rayCastHit.point != null)
                {
                    baseWorker.m_teleportPoint.transform.position = m_rayCastHit.point;
                    baseWorker.m_teleportPoint.SetActive(true);
                }
            }
            else
            {
                baseWorker.m_teleportPoint.SetActive(false);
            }

            baseWorker.drawLine();
        }

        private bool HitFloor(ref RaycastHit hit)
        {
            return 1 << hit.transform.gameObject.layer == LayerMask.GetMask("TransparentFX");
        }

        public void onTeleport(UnityEngine.Object sender, TDuVRControllerEventArgs e)
        {
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;
            if (currentHitPoint != Vector3.zero)
            {
                if (baseWorker.m_teleportPoint.activeInHierarchy)
                {
                    baseWorker.moveCameraPrefab(currentHitPoint);

                    currentHitPoint = Vector3.zero;
                    baseWorker.m_teleportPoint.SetActive(false);
                }
            }

            if (baseWorker.m_teleportLine.enabled == false)
                return;
            baseWorker.m_teleportLine.enabled = false;
        }

        public void hitCheck(UnityEngine.Object sender)
        {
            TDuSceneWorker baseWorker = (TDuSceneWorker)sender;

            m_ray.direction = baseWorker.m_currentController.transform.forward - baseWorker.m_currentController.transform.up * 0.25f;
            m_ray.origin = baseWorker.m_currentController.transform.Find("start").position;

            if (Physics.Raycast(m_ray, out m_rayCastHit))
            {
                m_currentHit = m_rayCastHit.transform;

                if (m_currentHit != null && m_lastHit != null && m_currentHit != m_lastHit)
                {
                    if (m_lastHit.GetComponent<Pvr_UIGraphicRaycaster>() && m_lastHit.transform.gameObject.activeInHierarchy && m_lastHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled)
                    {
                        m_lastHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled = false;
                    }
                }
                if (m_currentHit != null && m_lastHit != null && m_currentHit == m_lastHit)
                {
                    if (m_currentHit.GetComponent<Pvr_UIGraphicRaycaster>() && !m_currentHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled)
                    {
                        m_currentHit.GetComponent<Pvr_UIGraphicRaycaster>().enabled = true;

                    }
                }
                if (1 << m_rayCastHit.transform.gameObject.layer == LayerMask.GetMask("Water"))
                {
                    if (!m_noClick)
                        m_rayCastHit.transform.GetComponent<Renderer>().material = m_gazemat;

                    if (Controller.UPvr_GetKeyDown(0, Pvr_KeyCode.TOUCHPAD) || Controller.UPvr_GetKeyDown(1, Pvr_KeyCode.TOUCHPAD) || Input.GetMouseButtonDown(0))
                    {
                        m_referenceObj.transform.position = m_rayCastHit.point;

                        m_disX = m_rayCastHit.transform.position.x - m_referenceObj.transform.position.x;
                        m_disY = m_rayCastHit.transform.position.y - m_referenceObj.transform.position.y;
                        m_dragObj = m_rayCastHit.transform;
                    }
                    if (Controller.UPvr_GetKey(0, Pvr_KeyCode.TOUCHPAD) || Controller.UPvr_GetKey(1, Pvr_KeyCode.TOUCHPAD) || Input.GetMouseButton(0))
                    {
                        if (m_rayCastHit.transform == m_dragObj.transform)
                        {
                            m_referenceObj.transform.position = new Vector3(m_rayCastHit.point.x, m_rayCastHit.point.y, m_rayCastHit.transform.position.z);
                            m_dragObj.position = new Vector3(m_referenceObj.transform.position.x + m_disX, m_referenceObj.transform.position.y + m_disY, m_rayCastHit.transform.position.z);
                        }
                    }
                }

                m_lastHit = m_rayCastHit.transform;
#if UNITY_EDITOR
                Debug.DrawLine(m_ray.origin, m_rayCastHit.point, Color.red);
#endif
                baseWorker.m_currentController.transform.Find("dot").position = m_rayCastHit.point;
                if (Pvr_ControllerManager.Instance.LengthAdaptiveRay)
                {
                    float scale = 0.178f * baseWorker.m_currentController.transform.Find("dot").localPosition.z / 3.3f;
                    Mathf.Clamp(scale, 0.05f, 0.178f);
                    baseWorker.m_currentController.transform.Find("dot").localScale = new Vector3(scale, scale, 1);
                }
            }
            else
            {
                if (m_lastHit != null && 1 << m_lastHit.transform.gameObject.layer == LayerMask.GetMask("Water"))
                {
                    m_lastHit.transform.GetComponent<Renderer>().material = m_normat;
                }
                m_currentHit = null;
                m_noClick = false;

                if (Pvr_ControllerManager.Instance.LengthAdaptiveRay)
                {
                    baseWorker.m_currentController.transform.Find("dot").localScale = new Vector3(0.178f, 0.178f, 1);
                }
            }
#if UNITY_EDITOR
            baseWorker.m_rayLine.GetComponent<LineRenderer>().SetPosition(0, baseWorker.m_currentController.transform.TransformPoint(0, 0, 0.072f));
            baseWorker.m_rayLine.GetComponent<LineRenderer>().SetPosition(1, baseWorker.m_dot.transform.position);
#endif
            if (m_lastHit != null && 1 << m_lastHit.transform.gameObject.layer == LayerMask.GetMask("Water") && m_currentHit != null)
            {
                m_lastHit.transform.GetComponent<Renderer>().material = m_clickmat;
                m_noClick = true;
            }
        }
    }
}
